﻿using System;
using System.IO;
using System.Net;
using System.Text;
using ICSharpCode.SharpZipLib.BZip2;


namespace UpdateTableMarkets
{
	class Program
	{
		static void Main(string[] args)
		{
			/*
			 * Dans cet executable, il faut que je télécharge le fichier "incremental" de Eve-Metrics
			 * - que je le décompresse
			 * - que je l'insère dans une table temporaire (BULK INSERT)
			 * - que je fasses un MERGE avec la table Markets
			 * - et que je fasses les opérations de nettoyage (DELETE table.Temp, DELETE les Expired et BuyOrder)
			 * */

			// Je vais télécharger le fichier.
			var emplacementZip = TelechargeFichierCsv();
			// Si j'ai un retour ERROR, cela veut dire qu'il n'y avait pas de fichier à DL.
			if(emplacementZip == "ERROR")
				return;

			// Maintenant je décompresse le fichier BZ2, et le renomme en Last.csv.
			DecompresserLeFichier(emplacementZip);

			// Maintenant il faut que je modifie la fin de chaque ligne pour passer de \n --> \r\n
			MiseEnFormePourInsertion();

			// Méthodes qui travaillent sur la base.
			InsererDansTableTemp();
			EnleverLesBuyOrders();
			MergeDesDeuxTables();
			SupprimerLesExpired();
			ViderTemporaire();
		}

		/// <summary>
		/// Va permettre de remplacer les "\n" par des "\r\n"
		/// </summary>
		private static void MiseEnFormePourInsertion()
		{
			const string path = @"C:\CsvDecompresse\Last.csv";

			var fichierLu = File.ReadAllText(path);
			var nouveauFichier = fichierLu.Replace("\n", "\r\n");

			File.WriteAllText(@"C:\CsvDecompresse\NewLast.csv", nouveauFichier);
			File.Delete(path);
		}

		/// <summary>
		/// Télécharge le fichier Incrémental du site Eve-Metrics.
		/// </summary>
		/// <returns></returns>
		private static string TelechargeFichierCsv()
		{
			// Site ou télécharger : http://export.eve-metrics.com/orders/incremental/
			// Format du fichier : 2010-12-03.csv.bz2

			// Récupération de la date du Jour, et mise en forme en string.
			var aujourdhui = DateTime.Now;

			// Je transforme la date au format du fichier.
			string dateString = MiseEnFormeDate(aujourdhui, false);

			if (!Directory.Exists(@"C:\123"))
				Directory.CreateDirectory(@"C:\123");

			try
			{
				// Création d'un objet WebClient (c'est lui qui permet de télécharger un fichier)
				WebClient wc = new WebClient();

				LogMarkets.LogMoiCa(" - Début téléchargement. - " + dateString);
				// Lancement du téléchargement
				// argument 1 : url du fichier source
				// argument 2 : l'emplacement ou enregistrer le fichier sur le disque dur
				wc.DownloadFile("http://export.eve-metrics.com/orders/incremental/"+dateString, @"c:\123\"+dateString);
				// Destruction de l'objet WebClient
				wc.Dispose();

			}
			catch (Exception e)
			{
				LogMarkets.LogMoiCa(" - Erreur du téléchargement - "+ dateString + " - " + e.Message);
				return "ERROR";
			}
			LogMarkets.LogMoiCa(" - Téléchargement terminé. - " + dateString);
			return @"c:\123\" + dateString;
		}

		/// <summary>
		/// Pour mettre en forme la date du jour en nom du fichier attendu pour le téléchargement.
		/// </summary>
		/// <param name="aujourdhui"></param>
		/// <param name="csv"></param>
		/// <returns></returns>
		private static string MiseEnFormeDate(DateTime aujourdhui, bool csv)
		{
			// Exemple : 2010-12-03.csv.bz2, il faut que la sortie soit sous cette forme.
			StringBuilder sb = new StringBuilder();
			const string TIRE = "-";
			const string CSV = ".csv";
			const string FIN = ".bz2";
			string retourForme = string.Empty;

			if(csv)
			{
				retourForme =
				sb.Append(aujourdhui.Year).Append(TIRE).Append(aujourdhui.Month.ToString("00")).Append(TIRE).Append(aujourdhui.Day.ToString("00")).Append(CSV).ToString();
			}
			else
			{
				retourForme =
				sb.Append(aujourdhui.Year).Append(TIRE).Append(aujourdhui.Month.ToString("00")).Append(TIRE).Append(aujourdhui.Day.ToString("00")).Append(CSV).Append(FIN).
					ToString();
			}

			return retourForme;
		}

		/// <summary>
		/// Décompresse le fichier.
		/// </summary>
		/// <param name="cheminFichierZip"></param>
		private static void DecompresserLeFichier(string cheminFichierZip)
		{
			try
			{
				// Chemin de décompression du fichier.
				const string pathDecompress = @"c:\CsvDecompresse";

				// Si le répertoire n'existe pas, je le crée.
				if (!Directory.Exists(pathDecompress))
					Directory.CreateDirectory(pathDecompress);

				// Maintenant, je crée les 2 Streams (entrant le zip, et sortant le dézip).
				FileStream fileStream = new FileStream(cheminFichierZip, FileMode.Open);
				var total = pathDecompress + "\\Last.csv"; // Chemin et nom du fichier dezip.
				FileStream sortieStream = new FileStream(total, FileMode.CreateNew, FileAccess.Write);

				// Décompression.
				BZip2.Decompress(fileStream, sortieStream);
				File.Delete(cheminFichierZip);

				LogMarkets.LogMoiCa(" - Décompression terminé.");
			}
			catch(Exception e)
			{
				LogMarkets.LogMoiCa(" - Erreur sur la décompression - " + e.Message);
			}
		}

		/// <summary>
		/// Cet méthode va appeller la Proc Stock du BULK INSERT, pour mettre les données dans la table Temporaire.
		/// </summary>
		private static void InsererDansTableTemp()
		{
			LogMarkets.LogMoiCa(" - Début Insertion dans table.");

			DataClassesMarketsDataContext marketsBase = new DataClassesMarketsDataContext();
			marketsBase.CommandTimeout = 600;
			marketsBase.InsererMarkets();

			LogMarkets.LogMoiCa(" - Fin Insertion.");

			File.Delete(@"C:\CsvDecompresse\NewLast.csv");
		}

		/// <summary>
		/// Supprime dans la table temporaire (moins de ligne), tout les BuyOrders.
		/// </summary>
		private static void EnleverLesBuyOrders()
		{
			LogMarkets.LogMoiCa(" - Début suppression BuyOrders");

			DataClassesMarketsDataContext marketsBase = new DataClassesMarketsDataContext();
			marketsBase.CommandTimeout = 600;
			marketsBase.SupprimerBuyOrdersTemp();

			LogMarkets.LogMoiCa(" - Fin suppression BuyOrders");
		}

		/// <summary>
		/// Va fusionner les 2 tables.
		/// </summary>
		private static void MergeDesDeuxTables()
		{
			LogMarkets.LogMoiCa(" - Début MERGE");

			DataClassesMarketsDataContext marketsBase = new DataClassesMarketsDataContext();
			marketsBase.CommandTimeout = 600;
			marketsBase.MergeMarkets();

			LogMarkets.LogMoiCa(" - Fin MERGE");
		}

		/// <summary>
		/// Supprime toutes les lignes des SellOrders qui sont Expired
		/// </summary>
		private static void SupprimerLesExpired()
		{
			LogMarkets.LogMoiCa(" - Début suppression Expired");

			DataClassesMarketsDataContext marketsBase = new DataClassesMarketsDataContext();
			marketsBase.CommandTimeout = 600;
			marketsBase.Delete_Expired();

			LogMarkets.LogMoiCa(" - Fin suppression Expired");
		}

		/// <summary>
		/// Vide la table Temporaire, une fois tout fini.
		/// </summary>
		private static void ViderTemporaire()
		{
			LogMarkets.LogMoiCa(" - Début suppression Temporaire");

			DataClassesMarketsDataContext marketsBase = new DataClassesMarketsDataContext();
			marketsBase.CommandTimeout = 600;
			marketsBase.ViderTemp();

			LogMarkets.LogMoiCa(" - Début suppression Temporaire");
		}

	}
}
